//该控件用来管理页面上的所有widget
define(function(require, exports, module) {
    'use strict';

    var me = {};

    var GrandWidgetsMap = {};//用来存储控件的信息，比如attributes
    var GrandLayoutMap = {};//用来存储控件的layout，亦即父子相对关系
    var GrandEventsMap = {};//用来存储事件广播

    var isEditMode = (SESSION.prj === 'canvas');

    var _rk;
    me.setRk = function(rk) {
        _rk = rk;
        me._rk = _rk;
        //配合设计器做初始化动作
        if (isEditMode){
            $.extend(me, require('./formMgr_designer'));
            me.beEditMode({
                '_rk': _rk
            });
        }
    };

    if (seajs.data.dev) {
        $('body').on('click.xsydebug', function(e) {
            var el = $(e.target);
            var w = el.closest('[wtype][id]');
            if (e.ctrlKey) {
                var wid = w.attr('id')
                    // console.log(w.attr('wtype'), '#' + wid, '控件信息:', me.getWidgetInfo(wid));
            }
        });
    }
    $(window).unload(function() {
        //关闭时回传状态
    });

    { //性能监测统计
        me._cost_seajs = 0; //seajs加载时间
        me._cost_loaddata = 0; //加载数据所用时间
        me._cost_widget = 0; //控件js执行时间
        me._wcost = {};
    }

    me.runMethod = function(wid, fnName, a0,a1,a2,a3,a4){
        if((wid+'').indexOf('#') < 0) wid = '#'+wid;
        return $(wid).runMethod(fnName, a0,a1,a2,a3,a4)//偷懒，换成apply
    };

    me.cacheWidgetInfo = function(widgetInfo) {
        var uuid = widgetInfo.uuid + '';
        GrandWidgetsMap[uuid] = widgetInfo;
    };
    me.widgetIsExist = function(uuid){
        return !!me.getWidgetInfo(uuid);
    };
    me.getWidgetInfo = function(uuid) {
        if (!uuid) return null;
        var info = GrandWidgetsMap[uuid];
        var layout = me.getLayoutInfo(uuid);
        if(layout)info.children = layout.children;
        return info;
    };
    me.getWidgetsInfoByType = function(wtype, entityId) {
        var results = [];
        for(var uuid in GrandWidgetsMap){
            var item = GrandWidgetsMap[uuid];
            if(entityId !== null){
                if(item.widgetType === wtype && (entityId+'') === (item.childEntityId+'')) results.push(item);
            }else{
                if(item.widgetType === wtype) results.push(item);
            }
        }
        return results;
    };
    me.getWidgetInfoByEntityId = function(entityId) {
        if (!entityId) return null;
        for(var uuid in GrandWidgetsMap){
            var item = GrandWidgetsMap[uuid];
            if((item.childEntityId+'') == (entityId+'')) return item;
        }
    };
    me.getWidgetIdList = function(){
        var list = [];
        for(var id in GrandWidgetsMap){
            list.push(id);
        }
        return list;
    };
    me.getWidgetTypeList = function(){
        var list = [];
        for(var id in GrandWidgetsMap){
            var w = GrandWidgetsMap[id];
            if(w){
                list.push({
                    widgetType: w.widgetType,
                    entityId : w.childEntityId
                });
            }else{
                console.log('unknown uuid', id)
            }            
        }
        return list;
    };
    { //页面级滚动懒加载
        var scrollingContainer;
        var lazyrendering_timer;
        me.setScrollingContainer = function(elem) {
            scrollingContainer = elem;
            scrollingContainer.off('scroll.lazyrendering').on('scroll.lazyrendering', function() {
                if (!scrollingContainer) return;
                var scrollTop = scrollingContainer.scrollTop();
                var onlyChild = scrollingContainer.find('>.plantflom-tpl-pc');

                var scrollBottom = onlyChild.outerHeight() - scrollingContainer.height() - scrollTop;
                if (scrollBottom <= 0) scrollBottom = 0;

                me.broadcast('onCrmPanelScroll', {
                    dir: 'y',
                    scrollTop: scrollTop,
                    scrollBottom: scrollBottom
                });

                window.clearTimeout(lazyrendering_timer);
                lazyrendering_timer = window.setTimeout(function() {
                    lazyRendering(scrollTop, scrollBottom);
                }, 10);
            })
        };
        var lazyRendering = function(scrollTop, scrollBottom) {
            me.broadcast('onCrmPanelScrollDelay', {
                dir: 'y',
                scrollTop: scrollTop,
                scrollBottom: scrollBottom
            });

            var should = false;
            for (var uuid in GrandWidgetsMap) {
                var w = $('#' + uuid);
                if (w.is(':visible') && !w.data('widgetInited')) { //可见且未初始化
                    should = true;
                    break;
                }
            }
            if (!should) {
                window.clearTimeout(lazyrendering_timer);
                return;
            }
            window.setTimeout(function() { //这个延时是为了formMgr.whileScrolling可以准确获取scrollbottom的值，因为初始化widget会影响bottom
                $('[wtype]:visible').each(function(i, el) {
                    // console.log(el)
                    createWidget($(el))
                });
            }, 100);
        };
    } { //页面级事件广播
        me.addBroadcastListener = function(widgetId, eventName, callback) {
            var names = (String(eventName).match(/\S+/g) || []);
            names.forEach(function(eventName) {
                if (!GrandEventsMap[eventName]) {
                    GrandEventsMap[eventName] = {};
                }
                GrandEventsMap[eventName][widgetId] = {
                    callback: callback
                }
            });
        };
        me.broadcast = function(eventName) {
            var widgetIdList = GrandEventsMap[eventName];
            if (!widgetIdList) return;
            for (var uuid in widgetIdList) {
                var el = $('#' + uuid);
                var einfo = widgetIdList[uuid]; //event info
                var winfo = me.getWidgetInfo(uuid); //widget info
                if (einfo && einfo.callback) {
                    //(einfo.callback)();
                    var args = [];
                    if (arguments.length > 1) {
                        for (var j = 1, len = arguments.length; j < len; j++) args.push(arguments[j]);
                    }
                    einfo.callback.apply(el, args);
                }
            }
        };
    }
    me.initScope = function(targetElem, saveJson) {
        var layout = saveJson.config.layout;
        var widgets = saveJson.config.widgets;

        for (var uuid in widgets) {
            widgets[uuid].uuid = uuid;
        }

        window.ttt1 = new Date();
        initGrandWidgetsInfo(layout, widgets);
        initScopeWidgets(layout);
        createWidget(targetElem, layout);
        if (window.ttt0) { //性能
            window.ttt2 = new Date();
            var cost1_0 = (window.ttt1 - window.ttt0);
            var cost2_1 = (window.ttt2 - window.ttt1);
            _rk.formMgr._cost_loaddata += cost1_0;
            _rk.formMgr._cost_widget += cost2_1;
            // console.log('%c性能监测（后端）：layout请求：' + cost1_0 + 'ms', "color:red;background-color:#ffffcc;")
            // console.log('%c性能监测（JS）：组件初始化：' + cost2_1 + 'ms', "color:red;background-color:#ffffcc;")
        }
        _rk.runDesignerMethod('designer.handleCanvasChanged');//通知外界更新
    };
    var initGrandWidgetsInfo = function(layoutInfo, widgets) {
        foreachChildren(layoutInfo, function(info) {
            var uuid = info.uuid;
            var winfo = widgets[uuid];
            for (var key in winfo) {
                info[key] = winfo[key];
            }
        });
        updateParentId(layoutInfo);//需要parentId，可以逆向查找
        GrandLayoutMap = $.extend(true, {}, layoutInfo);
        //console.log(GrandLayoutMap)
    };
    var initScopeWidgets = function(layoutInfo) {
        foreachChildren(layoutInfo, function(info) {
            initWidget(info);
        });
    };
    var updateParentId = function(layoutInfo) {
        var pid = layoutInfo.uuid;
        var children = layoutInfo.children;
        if (children) {
            if ($.isArray(children)) {
                for (var i = 0, len = children.length; i < len; i++) {
                    children[i].pid = pid;
                    updateParentId(children[i]);
                }
            } else {
                for (var key in children) {
                    var arr = children[key];
                    for (var i = 0, len = arr.length; i < len; i++) {
                        arr[i].pid = pid;
                        updateParentId(arr[i]);
                    }
                }
            }
        }
    };
    var foreachChildren = function(layoutInfo, callback) {
        (callback)(layoutInfo);
        var children = layoutInfo.children;
        if (children) {
            if ($.isArray(children)) {
                for (var i = 0, len = children.length; i < len; i++) {
                    foreachChildren(children[i], callback)
                }
            } else {
                for (var key in children) {
                    var arr = children[key];
                    for (var i = 0, len = arr.length; i < len; i++) {
                        foreachChildren(arr[i], callback)
                    }
                }
            }
        }
    };
    me.foreachChildren = foreachChildren;
    
    var initWidget = function(widgetInfo) {
        var uuid = widgetInfo.uuid + '';
        var widgetType = widgetInfo.widgetType;

        me.cacheWidgetInfo(widgetInfo); //缓存信息

        // var elem = $('#' + uuid);
        // try{
        //     elem[widgetType](widgetInfo.attributes);
        // }catch(e){
        //     console.error('error: ' + widgetType)
        // }
    };
    var getRandomId = function(){
        return '8' + (Math.round(Math.random() * 100000) + '8').replace(/\./g, '');
    };
    me.getRandomId = getRandomId;
    var createWidget = function(targetElem, widgetInfo) {
        var widgetId = targetElem.attr('id');
        var widgetType = targetElem.attr('wtype');

        if (!targetElem._force_init) {
            var stopInit = false;
            if (targetElem.data('widgetInited') || !targetElem.is(':visible')) stopInit=true; //已经初始化过了 || 不可见，不初始化
            if (scrollingContainer) {
                var $sc = $(scrollingContainer),
                    heightFix = 210; /*模块占位与模块最小高度之差 * 3 */
                // if (targetElem.position().top > $sc.innerHeight() + $sc.scrollTop() + 210 /*模块占位与模块最小高度差 * 3 */ ) return; //不在滚动条可见区域
                // console.log([widgetId, targetElem.offset().top, targetElem.scrollParent().offset().top, $sc.innerHeight() + $sc.scrollTop() + heightFix]);
                if (targetElem.offset().top - targetElem.scrollParent().offset().top > $sc.innerHeight() + $sc.scrollTop() + heightFix) stopInit=true; //不在滚动条可见区域
            }
            var $bdy = $('body');
            if (targetElem.offset().top > ($bdy.height() + $bdy.prop('scrollTop') + heightFix)) stopInit=true; //不在滚动条可见区域2
            if(!isEditMode && stopInit) return;
            if (!widgetType) {
                targetElem.find('[wtype]').each(function(i, el) {
                    var el = $(this)
                    createWidget(el);
                });
                return;
            }
        }
        if(targetElem.data('widgetInited'))return;
        if (typeof widgetInfo == undefined || !widgetInfo) widgetInfo = me.getWidgetInfo(widgetId);
        if (!widgetInfo) {
            var uuid = getRandomId();
            if(targetElem.attr('id')) uuid = targetElem.attr('id');
            widgetInfo = {
                uuid: uuid,
                widgetType: widgetType
            };
            targetElem.attr('id', uuid);
            me.cacheWidgetInfo(widgetInfo);
        }
        if (!widgetInfo.userPermission) {
            widgetInfo.userPermission = 'all'; //默认允许所有
        } else {
            if (widgetInfo.userPermission.l === 0) {
                //终止渲染，无权限查看
                return;
            }
        }
        var widgetType = widgetInfo.widgetType;
        var widgetId = targetElem.attr('id');
        var options = widgetInfo;
        // if(widgetInfo.attributes){
        //     for(var key in widgetInfo.attributes){
        //         options[key] = widgetInfo.attributes[key];
        //     }
        // }
        if (!$.fn[widgetType]) {
            console.error('nowidget found: ' + widgetType);
            return;
        }
        var t1 = new Date();
        targetElem.addClass('xsy_widget_loading');
        targetElem.addClass(widgetType);
        var widgetElem;
        if (targetElem.attr('wtype') && targetElem.attr('wtype') == widgetType) {
            widgetElem = targetElem;
            widgetElem[widgetType](options);
            widgetElem.data('widgetInited', true);
        } else {
            widgetElem = targetElem.find('[wtype="' + widgetType + '"]');
            widgetElem[widgetType](options).data('widgetInited', true);
        }
        targetElem.removeClass('xsy_widget_loading');
        widgetInfo._inited = true;
        if (seajs.data.dev) { //叶子节点控件性能监测
            var t2 = new Date();
            if (!widgetInfo.children) {
                if (!_rk.formMgr._wcost[widgetId]) _rk.formMgr._wcost[widgetId] = {};
                var cost = (t2 - t1);
                _rk.formMgr._wcost[widgetId].init = cost;
            }
        }
        if(isEditMode){
            widgetElem.each(function(i, el){
                el = $(el);
                var wtype = el.attr('wtype');
                var entityId = el.attr('entityid');
                var candrag = me.canDrag(wtype, entityId);
                //console.log('cd', wtype, entityId, candrag)
                if(candrag) el.addClass('xsy_designer_draggable')
            });
            me.beEditingDragDrop();
        }
    };
    me.createWidget = createWidget;

    me.exportWidgets = function(){
        return $.extend(true, {}, GrandWidgetsMap);
    };
    me.exportLayoutJson = function(){
        //对GrandLayoutMap的json结构进行清理，留下干净的layout结构
        var layout = me.getLayout(true);
        me.foreachChildren(layout, function(node){
            for(var key in node){
                if(key !== 'children' && key !=='uuid') delete node[key];
            }
        });
        return layout;
    };
    me.getLayout = function(clone){
        if(typeof clone === 'undefined') clone = false;
        return clone ? $.extend(true, {}, GrandLayoutMap) : GrandLayoutMap;
    };
    me.getLayoutInfo = function(wid, clone){
        if(typeof clone === 'undefined') clone = false;
        var result;
        foreachChildren(GrandLayoutMap, function(info) {
            var uuid = info.uuid;
            if(uuid === wid){
                result = info;
            }
        });
        return clone ? $.extend(true, {}, result) : result;;
    };
    me.updateAttributes = function(wid, attributes){
        var  elem = $('#' + wid);

        if(!elem) {return;}
        var widgetType = elem.attr('wtype');
        if($.rk[widgetType] && $.rk[widgetType].prototype && $.rk[widgetType].prototype.previewRender){
            elem[widgetType]('previewRender', attributes);
        }
        

        return $.extend(true, {}, attributes);
    };
    me.updateLayout = function(wid, newchildren){
        var oldlayout = me.getLayoutInfo(wid);
        console.log('oldlayout', oldlayout, 'newchildren', newchildren)
        var oldchildrenMap = {};
        for(var i=0,len=oldlayout.children.length;i<len;i++){
            var child = oldlayout.children[i];
            var childid = child.uuid;
            oldchildrenMap[childid] = child;
        }
        oldlayout.children = [];
        for(var i=0,len=newchildren.length;i<len;i++){
            var newchild = newchildren[i];
            var newchildid = newchild.uuid + '';
            if(oldchildrenMap[newchildid]){
                var oldChildren = $.extend(oldchildrenMap[newchildid], newchild);
                $.extend(GrandWidgetsMap[newchildid].attributes, newchild.attributes);
                oldlayout.children.push(oldChildren);
            }else{
                var newid = getRandomId();
                var newinfo = {
                    attributes: newchild.attributes,
                    pid: wid,
                    uuid: newid,
                    widgetType: "xsyDiv"
                };
                oldlayout.children.push(newinfo);
                if(!GrandWidgetsMap[newid]) GrandWidgetsMap[newid] = newinfo;
            }
        }
        console.log('oldlayout.children', oldlayout.children)
        console.log('GrandLayoutMap', GrandLayoutMap)
        console.log('GrandWidgetsMap', GrandWidgetsMap)
        return $.extend(true, [], oldlayout.children);
    };
    me.deleteWidget = function(wid){
        console.log('DND: deleteWidget():', wid);
        var winfo = GrandWidgetsMap[wid];
        var pid = winfo.pid;
        var wlayout = me.getLayoutInfo(wid);
        var cachedInfo = $.extend(true, {}, winfo);
        //清除信息
        delete GrandWidgetsMap[wid];
        foreachChildren(wlayout, function(childinfo){
            delete GrandWidgetsMap[childinfo.uuid];
        });
        rejectChildren(wid, pid);
        $('#' + pid).runMethod('handleChildDeleted');//触发容器的handle事件，可能会各自有处理
        //需要删除所有后续子节点
        $('#' + wid).remove();
        //console.log(' -why?', wid, $('#'+wid).size())
        specialTreatementForWidgetRemoved(cachedInfo);
        _rk.runDesignerMethod('designer.handleCanvasChanged');//通知外界更新
    };
    var rejectChildren = function(wid, pid){
        var playout = me.getLayoutInfo(pid);
        if(!playout) {
            return;
        }
        var children = playout.children;
        if (children) {
            if ($.isArray(children)) {
                playout.children = _.reject(children, function(obj){ return obj.uuid == wid; });
            } else {
                for (var key in children) {
                    playout.children[key] = _.reject(children[key], function(obj){ return obj.uuid == wid; });
                }
            }
        }
        //for grandwidgetsmap
        var playout = GrandWidgetsMap[pid];
        if(!playout) {
            return;
        }
        var children = playout.children;
        if (children) {
            if ($.isArray(children)) {
                playout.children = _.reject(children, function(obj){ return obj.uuid == wid; });
            } else {
                for (var key in children) {
                    playout.children[key] = _.reject(children[key], function(obj){ return obj.uuid == wid; });
                }
            }
        }
    };
    me.showIndicator = function(act/*before,after,in*/, targetId, subLayoutName/*left,right,head,body*/){
        return me.addWidget('indicator', act, targetId, subLayoutName);
    };
    me.moveWidget = function(wid, act, targetId, subLayoutName){
        var winfo = me.getWidgetInfo(wid);
        var cachedInfo = $.extend(true, {}, winfo);
        var result = me.addWidget(wid, act, targetId, subLayoutName);
        specialTreatementForWidgetRemoved(cachedInfo);//移动约等于删除粘贴，因此需要执行以下
        return result;
    };
    me.addWidget = function(winfo, act/*before,after,in*/, targetId, subLayoutName/*left,right,head,body*/){
        var targetElem = $('#'+targetId);
        var targetInfo = me.getWidgetInfo(targetId);
        if(!targetInfo){
            console.log(targetId)
            return;
        }
        var comingType;
        var wElem;
        var wHtml;
        if(winfo === 'indicator' || winfo === 'wrong_indicator'){
            //是拖拽的占位符，用来示意drop位置
            $('#drop_indicator').remove();
            wHtml = '<div id="drop_indicator" class="xsy_drop_indicator"><span style="display:none;">'+act+', '+targetId+'('+targetInfo.widgetType+'),'+subLayoutName+'</span></div>';
            comingType = 'indicator';
        }else if(typeof winfo === 'string'){
            //是控件id，是一个已存在的控件move到该位置
            comingType = 'widget';
            wHtml = $('#' + winfo)
        }else{
            if(winfo._designer_maximumInstanceCount === 1 && _rk.formMgr.getWidgetsInfoByType(winfo.widgetType, winfo.childEntityId).length > 0){
                //页面json中已存在的单实例控件，但由于是hidden状态未被初始化
                var widgetinfo = _rk.formMgr.getWidgetInfoByEntityId(winfo.childEntityId);
                if(!widgetinfo) widgetinfo = _rk.formMgr.getWidgetsInfoByType(winfo.widgetType)[0];
                var uuid = widgetinfo.uuid;
                if($('#'+uuid).size() === 1){//html已经绘制到dom上了，需要move
                    comingType = 'widget';
                    wHtml = $('#'+uuid);
                    winfo = uuid;
                }else{
                    rejectChildren(uuid, widgetinfo.pid);
                    winfo = widgetinfo;
                    wHtml = '<div id="'+uuid+'" wtype="'+widgetinfo.widgetType+'"></div>';
                    comingType = 'new';   
                }
            }else{
                //是普通添加
                //是info，则是新建一个控件
                if(!winfo.uuid){
                    winfo.uuid = getRandomId();
                }
                wHtml = '<div id="'+winfo.uuid+'" wtype="'+winfo.widgetType+'"></div>';
                comingType = 'new';                
            }
        }
        var parentId, parentElem;
        if(act === 'before' || act ==='after'){
            parentId = targetInfo.pid;
            parentElem = $('#' + parentId);
            var container = $('#'+targetId).closest('.xsy_designer_droppable');
            $(targetElem)[act](wHtml);
        }else if(act === 'in'){
            parentId = targetId;
            parentElem = $('#'+targetId);
            var containerElem;
            if(subLayoutName){
                containerElem = parentElem.find('.xsy_designer_droppable[data-layout="'+subLayoutName+'"]:first');
            }else{
                containerElem = parentElem.find('.xsy_designer_droppable:first');
            }
            var lastElem = containerElem.find('>[id][wtype]:last');
            if(lastElem.size() == 0){
                containerElem.append('<div act="for_append">ffdd</div>');
                lastElem = containerElem.find('[act="for_append"]');
            }
            $(lastElem).after(wHtml);
            containerElem.find('[act="for_append"]').remove();
        }
        if(comingType === 'indicator') return;
        //console.log('DND: addWidget():', winfo, act, targetId, subLayoutName);
        if(comingType === 'widget') {
            me.createWidget($('#' + winfo));
            var infoWidthChildren = me.getLayoutInfo(winfo, true);
            me.farewellWidget(winfo);
            //console.log('WHA', infoWidthChildren, targetId, act, subLayoutName);
            if(act === 'in')parentElem.runMethod('handleChildAdded', winfo, act, subLayoutName);
            me.registWidget(infoWidthChildren, targetId, act, subLayoutName);
            afterWidgetLayoutChanged(infoWidthChildren.uuid);
            specialTreatementForWidgetAddMove(infoWidthChildren.uuid);
            return;
        }
        if(comingType === 'new') {
            me.registWidget(winfo, targetId, act, subLayoutName);
            me.createWidget($('#' + winfo.uuid));
            parentElem.runMethod('handleChildAdded', winfo, act, subLayoutName);
            afterWidgetLayoutChanged(winfo.uuid);
            specialTreatementForWidgetAddMove(winfo.uuid);
        }
        _rk.runDesignerMethod('designer.handleCanvasChanged');//通知外界更新
        return winfo;
    };
    var specialTreatementForWidgetRemoved = function(winfo){
        //console.log(' -removed', winfo.widgetType)
        if((/(Refer)$/g).test(winfo.widgetType)){//卡片控件必须被卡片容器包裹
            var wid = winfo.uuid;
            var pid = winfo.pid;
            var pinfo = me.getWidgetInfo(pid);
            //console.log('ok, id:', winfo.widgetType,'pid:', pid,'pinfo:', pinfo)
            if(pinfo.widgetType === 'xsyReferContainer' && $.isArray(pinfo.children) && pinfo.children.length === 0){
                //console.log(' -delparent', pinfo.uuid)
                me.deleteWidget(pinfo.uuid);
            }
        }
    };
    var specialTreatementForWidgetAddMove = function(wid){
        var winfo = me.getWidgetInfo(wid);
        if((/(Refer)$/g).test(winfo.widgetType)){//卡片控件必须被卡片容器包裹
            var wid = winfo.uuid;
            var pid = winfo.pid;
            var pinfo = me.getWidgetInfo(pid);
            console.log('ok, id:', winfo.widgetType,'pid:', pid,'pinfo:', pinfo)
            if(pinfo.widgetType !== 'xsyReferContainer'){
                var pinfo = {
                    widgetType: 'xsyReferContainer',
                    attributes: {}
                };
                var npinfo = me.addWidget(pinfo, 'after', wid);
                me.moveWidget(wid, 'in', npinfo.uuid)
            }
        }
    };
    var afterWidgetLayoutChanged = function(wid){
        me.beSelect(wid);
        _rk.runDesignerMethod('designer.editor.show', wid);
    };
    //自身所在的list
    var getLivingChildrenList = function(arg0, arg1){//获得自身所在children list
        if(typeof arg1 === 'undefined'){
            var targetId = arg0;
            var pid = me.getWidgetInfo(targetId).pid;
            var playout = me.getLayoutInfo(pid);
            return getLivingChildrenList2(playout, targetId);
        }else{
            var playout = arg0;
            var targetId = arg1;
            return getLivingChildrenList2(playout, targetId);
        }
    }
    me.getLivingChildrenList = getLivingChildrenList;
    var getLivingChildrenList2 = function(playout, targetId){
        var childrenlist;
        if($.isArray(playout.children)){
            childrenlist = playout.children;
        }else{
            for(var key in playout.children){
                var children = playout.children[key];
                for(var i=0,len=children.length;i<len;i++){
                    if(children[i].uuid === targetId) return children;
                }
            }
        }
        return childrenlist;
    };
    //自身位于list的第几个
    var getLivingIndex = function(livinglist, targetId){
        var at;
        for(var i=0,len=livinglist.length;i<len;i++){
            if(livinglist[i].uuid === targetId) {
                at = i;
                break;
            }
        }
        return at;
    };
    me.cutoffWidget = function(wid){//在父类中删除控件信息
        var livinglist = getLivingChildrenList(wid);
        var at = getLivingIndex(livinglist, wid);
        var cutted = livinglist.splice(at, 1);
        return cutted[0];
    };
    me.farewellWidget = function(wid){//在GrandXXX中，删除该控件的信息
        me.cutoffWidget(wid);
        delete GrandWidgetsMap[wid];
    };
    me.registWidget = function(winfo, targetId, act, subLayoutName){
        winfo = $.extend(true, {}, winfo);//cut off
        var pid;
        var targetInfo = me.getWidgetInfo(targetId);
        if(!winfo.attributes)winfo.attributes = {};
        if($.isArray(winfo.children)){
            for(var i=0,len=winfo.children.length;i<len;i++){
                var child = winfo.children[i];
                if(!child.uuid)child.uuid = getRandomId();//赐id
                if(!child.pid)child.pid = winfo.uuid;
            }
        }
        if(act === 'before' || act ==='after'){
            pid = targetInfo.pid;
            var playout = me.getLayoutInfo(pid);
            //console.log('------------' + JSON.stringify(playout))
            //console.log('targetId', targetId, targetInfo)
            var childrenlist = getLivingChildrenList(playout, targetId);
            var at = getLivingIndex(childrenlist, targetId);
            if(act === 'after') at++;
            winfo.pid = pid;
            childrenlist.splice(at, 0, winfo);            
            //console.log('playout', playout)
        }else if(act === 'in'){
            pid = targetId;
            var playout = me.getLayoutInfo(pid);
            var childrenlist;
            if($.isArray(playout.children)){
                childrenlist = playout.children;
            }else if(!playout.children){
                playout.children = [];
                childrenlist = playout.children;
            }else{
                if(!playout.children[subLayoutName])playout.children[subLayoutName] = [];
                childrenlist = playout.children[subLayoutName];
            }
            winfo.pid = pid;
            childrenlist.push(winfo);
            //console.log('playout', playout)
        }
        GrandWidgetsMap[winfo.uuid] = winfo;
        if($.isArray(winfo.children)){
            for(var i=0,len=winfo.children.length;i<len;i++){
                var child = winfo.children[i];
                if(!GrandWidgetsMap[child.uuid]){
                    GrandWidgetsMap[child.uuid] = child;
                }else{
                    $.extend(true, GrandWidgetsMap[child.uuid], child);
                }
            }
        }
    };
    var insertElem = function(html, targetId, act/*before,after,into*/, subLayoutName/*left,right,head,body*/){

    };

    me.isInited = function(uuid) {
        return !!$('#' + uuid).data('widgetInited');
    };
    me.handleErrorStatus = function(status) {
        switch (status) {
            case 300001:
                $('#crm-panel').html(require('./tpl/status_300001.tpl'));
                break;
            case 300002:
                $('#crm-panel').html(require('./tpl/status_300002.tpl'));
                break;
            default:
                ;
                break;
        }
        _rk.setTitle('');
        $('#crm-panel').find('a.xsy_detail_noaccess_return').click(function() {
            window.close();
        });
    };


    module.exports = me;
});
